<template>
  <div class="cropper-warp">
    <a-row>
      <a-col flex="auto" class="cropper-warp-left">
        <img id="image-warp" class="cropper-warp-left-img" ref="imageRef" :src="cropperImg"/>
      </a-col>
      <a-col flex="120px" class="cropper-warp-right">
        <div>预览</div>
        <img v-if="cropperImgBase64" class="cropper-warp-right-value-img" :src="cropperImgBase64"/>
        <div>100 x 100</div>
      </a-col>
    </a-row>
    <a-row style="marginTop: 16px;">
      <a-col :span="18">
        <a-button-group type="primary">
          <a-tooltip content="拖拽图片模式(图片可移动)">
            <a-button @click="setDragMode('move')"><icon-drag-arrow /></a-button>
          </a-tooltip>
          <a-tooltip content="拖拽图片模式(形成新的裁剪框)">
            <a-button @click="setDragMode('crop')"><icon-scissor /></a-button>
          </a-tooltip>
        </a-button-group>
        <a-button-group type="primary">
          <a-tooltip content="放大0.1">
            <a-button @click="zoom(0.1)"><icon-zoom-in /></a-button>
          </a-tooltip>
          <a-tooltip content="缩小0.1">
            <a-button @click="zoom(-0.1)"><icon-zoom-out /></a-button>
          </a-tooltip>
        </a-button-group>
        <a-button-group type="primary">
          <a-tooltip content="图片向左移动10">
            <a-button @click="move(-10, 0)"><icon-arrow-left /></a-button>
          </a-tooltip>
          <a-tooltip content="图片向右移动10">
            <a-button @click="move(10, 0)"><icon-arrow-right /></a-button>
          </a-tooltip>
          <a-tooltip content="图片向上移动10">
            <a-button @click="move(0, -10)"><icon-arrow-up /></a-button>
          </a-tooltip>
          <a-tooltip content="图片向下移动10">
            <a-button @click="move(0, 10)"><icon-arrow-down /></a-button>
          </a-tooltip>
        </a-button-group>
        <a-button-group type="primary">
          <a-tooltip content="向左旋转45°">
            <a-button @click="rotate(-45)"><icon-rotate-left /></a-button>
          </a-tooltip>
          <a-tooltip content="向右旋转45°">
            <a-button @click="rotate(45)"><icon-rotate-right /></a-button>
          </a-tooltip>
        </a-button-group>
        <a-button-group type="primary">
          <a-tooltip content="显示裁剪框">
            <a-button @click="crop()"><icon-check /></a-button>
          </a-tooltip>
          <a-tooltip content="清除裁剪框">
            <a-button @click="clear()"><icon-close /></a-button>
          </a-tooltip>
          <a-tooltip content="重置">
            <a-button @click="reset()"><icon-loop /></a-button>
          </a-tooltip>
        </a-button-group>
      </a-col>
    </a-row>
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted } from 'vue';

  import Cropper from 'cropperjs';
  import 'cropperjs/dist/cropper.css';

  const props = defineProps({
    // 文件
    file: {
      type: Object,
      default() {
        return {
          url: '',
          path: '',
          field: '',
        };
      },
    },
    imgType: {
      type: String,
      default: 'image/jpeg',
    },
  });
  const emit = defineEmits(['cropperOkCallback']);

  const imageRef = ref<HTMLImageElement>();
  const cropperImg = ref();
  const cropperImgBase64 = ref();
  const cropper = ref();

  const defaultOptions: Cropper.Options = {
    viewMode: 1, // 视图模式
    // dragMode: 'none', // 拖拽模式
    // initialAspectRatio: 1, // 裁剪框宽高比的初始值 默认与图片宽高比相同 只有在aspectRatio没有设置的情况下可用
    aspectRatio: 1, // 裁剪框的宽高比
    // preview: '.before', // 添加额外的元素(容器)以供预览
    responsive: true, // 在窗口尺寸调整后 进行响应式的重渲染 默认true
    restore: true, // 在窗口尺寸调整后 恢复被裁剪的区域 默认true
    checkCrossOrigin: true, // 检查图片是否跨域 默认true 如果是 会在被复制的图片元素上加上属性crossOrigin 并且在src上加上一个时间戳 避免重加载图片时因为浏览器缓存而加载错误
    checkOrientation: true, // 检查图片的方向信息（仅JPEG图片有）默认true 在旋转图片时会对图片方向值做一些处理 以解决IOS设备上的一些问题
    modal: true, // 是否显示图片和裁剪框之间的黑色蒙版 默认true
    guides: true, // 是否显示裁剪框的虚线 默认true
    center: true, // 是否显示裁剪框中间的 ‘+’ 指示器 默认true
    highlight: true, // 是否显示裁剪框上面的白色蒙版 （很淡）默认true
    background: true, // 显示容器的网格背景【默认true，显示马赛克背景，false时显示灰色背景色】
    autoCrop: true, // 允许初始化时自动的裁剪图片 配合 data 使用 默认true
    // autoCropArea: 0.6, // 设置裁剪区域占图片的大小 值为 0-1 默认 0.8 表示 80%的区域
    movable: true, // 是否可以移动图片 默认true
    rotatable: true, // 是否可以旋转图片 默认true
    scalable: true, // 是否可以缩放图片（可以改变长宽） 默认true
    zoomable: true, // 是否可以缩放图片（改变焦距） 默认true
    zoomOnTouch: true, // 是否可以通过拖拽触摸缩放图片 默认true
    zoomOnWheel: true, // 是否可以通过鼠标滚轮缩放图片 默认true
    wheelZoomRatio: 0.1, // 设置鼠标滚轮缩放的灵敏度 默认 0.1
    cropBoxMovable: true, // 是否可以拖拽裁剪框 默认true
    cropBoxResizable: true, // 是否可以改变裁剪框的尺寸 默认true
    toggleDragModeOnDblclick: true, // 是否可以通过双击切换拖拽图片模式（move和crop）默认true 当拖拽图片模式为none时不可切换 该设置必须浏览器支持双击事件
  };

  // 回调
  const cropperCBK = () => {
    emit('cropperOkCallback', cropperImgBase64.value);
  };
  const getCropData = () => {
    return cropper.value?.getCroppedCanvas()?.toDataURL(props.imgType);
  };
  const getCropBlob = () => {
    let file: any = '';
    cropper.value.getCroppedCanvas().toBlob((blob: any) => {
      file = blob;
    }, props.imgType);
    return file;
  };
  const getCropFile = (fileName = 'fileName.jpg') => {
    let file: any = '';
    cropper.value.getCroppedCanvas().toBlob((blob: any) => {
      file = new File([blob], fileName, {type: props.imgType});
    }, props.imgType);
    return file;
  };
  // 初始化cropperjs图片裁剪
  const initCropper = (imgUrl?: string) => {
    if (imgUrl) {
      cropperImg.value = imgUrl;
    }
    // const image: any = document.getElementById('image-warp');
    // const image = document.querySelector('#image-warp') as HTMLImageElement;
    const image: any = imageRef.value;
    if (cropper.value) {
      cropper.value.destroy();
    }
    cropper.value = new Cropper(image, {
      ...defaultOptions,
      crop(event) {
        // console.log(event.detail.x);
        // console.log(event.detail.y);
        // console.log(event.detail.width);
        // console.log(event.detail.height);
        // console.log(event.detail.rotate);
        // console.log(event.detail.scaleX);
        // console.log(event.detail.scaleY);
        cropperImgBase64.value = getCropData();
        cropperCBK();
      },
    });
  };

  // 拖拽图片模式
  const setDragMode = (move: string) => {
    cropper.value.setDragMode(move);
  };
  // 缩放
  const zoom = (ratio: number) => {
    cropper.value.zoom(ratio);
  };
  // 移动图片
  const move = (offsetX: number, offsetY: number) => {
    cropper.value.move(offsetX, offsetY);
  };
  // 旋转图片
  const rotate = (degree: number) => {
    cropper.value.rotate(degree);
  };
  // 显示裁剪框
  const crop = () => {
    cropper.value.crop();
  };
  // 清除裁剪框
  const clear = () => {
    cropper.value.clear();
  };
  // 重置
  const reset = () => {
    cropper.value.reset();
  };

  onMounted(async () => {
    // initCropper(); // 初始化
    cropperImg.value = props.file.url;
  });
  // 暴露方法【给父级调用】
  defineExpose({
    initCropper,
    getCropData,
    getCropBlob,
    getCropFile,
  });
</script>

<style lang="less">
  .cropper-warp {
    .cropper-warp-left {
      height: 350px;
      .cropper-warp-left-img {
        width: 100%;
        height: 100%;
      }
    }
    .cropper-warp-right {
      padding-left: 20px;
      .cropper-warp-right-value-img {
        width: 100px;
        height: 100px;
        border-radius: var(--el-border-radius-circle);
      }
    }
  }

  .arco-btn-group {
    margin-bottom: 10px;
    margin-right: 10px;
  }
</style>
